import React from 'react'
import Component, { mapStateToProps, mapDispatchToProps } from '@components/Component'
import { connect } from 'react-redux'
import style from './DocumentManage.module.less'
import { Button, Input, message, List, Space, Modal, Select } from 'antd'
import FreeScrollBar from 'react-free-scrollbar'
import { LoadingOutlined, ExclamationCircleOutlined } from '@ant-design/icons'
import { Document, Page } from 'react-pdf'
import { addScrollEvent, delScrollEvent } from '@redux/actions'
import Model from '@components/DocumentManage/Model'
const { confirm } = Modal
const { Option } = Select
class DocumentManage extends Component {
  state = {
    ready: false,
    loadingList: false,
    fixedMenuStyle: {},
    templateList: [],
    filterTemplateList: [],
    currentTemplateid: '',
    templateUserDefine: 0,
    file: null,
    visible: false,
    modifyTemplate: null,
    searchText: '',
    templateIdMap: {},
    userDefine: 1,
    fileTypes: [],
    justyModifyFile: false
  }

  docBoxRef = React.createRef()

  fixHandle (e) {
    const t = window.document.documentElement.scrollTop
    if (t > 80) {
      this.setState({
        fixedMenuStyle: { position: 'fixed', top: 80, left: '232px' }
      })
    } else {
      this.setState({
        fixedMenuStyle: {}
      })
    }
  }

  // 获取文书模板列表
  getTemplateList () {
    this.setState({ loadingList: true })
    this.$get('/api/xapc/file_template', {
      current: 1,
      page_size: 10000
    }).then(res => {
      this.setState({ loadingList: false })
      if (res.status === 1) {
        const l = res.data.list
        const map = {}
        l.forEach(i => {
          map[i.id] = i
        })
        const filterTemplateList = this.getTemlateList(l)
        const currentTemplateid = this.state.currentTemplateid
        const d = {
          templateList: l,
          templateIdMap: map,
          filterTemplateList,
          currentTemplateid: currentTemplateid || (filterTemplateList.length ? filterTemplateList[0].id : '')
        }
        this.setState(d, () => {
          this.onSearch(this.state.searchText)
          const id = this.state.currentTemplateid
          if (id) {
            this.getTemplateById(id)
          }
        })
      } else {
        message.warning(res.message)
      }
    }).catch(() => this.setState({ loadingList: false }))
  }

  onSearch (text) {
    this.setState({
      searchText: text
    }, () => {
      this.getTemplateListAfterFilter()
    })
  }

  // 根据搜索结果并获取文件模板
  getTemplateListAfterFilter () {
    this.setState({
      filterTemplateList: this.getTemlateList(this.state.templateList)
    })
  }

  getTemlateList (list) {
    return list.filter(li => {
      return li.title.indexOf(this.state.searchText) !== -1 && li.user_define === this.state.userDefine
    })
  }

  // 根据id获取模板
  getTemplateById (tempid) {
    const hide = message.loading('获取文书模板中')
    this.$get(`/api/xapc/file_template/${tempid}`)
      .then(res => {
        hide()
        if (res.status === 1) {
          this.setState({
            file: res.data
          })
        } else {
          message.warning(res.message)
        }
      }).catch(() => hide())
  }

  // 初始化文件参数
  initDoc (o) {
    const width = this.docBoxRef.current.offsetWidth
    this.setState({
      numPages: o.numPages,
      ready: true,
      width,
      height: width * 1.4140625
    })
  }

  // 新增文书按钮回调
  addHandle () {
    this.setState({
      visible: true,
      modifyTemplate: { user_define: 0 }
    })
  }

  submitHandle (d, callback) {
    if (d.id) {
      this.modifyRequest(d, callback)
    } else {
      this.addRequest(d, callback)
    }
  }

  // 添加文档请求
  addRequest (d, callback) {
    const hide = message.loading('添加文书模板中', 120)
    const formData = new FormData()
    formData.append('title', d.title)
    formData.append('code_type', d.code_type)
    if (d.file && d.file.file) {
      formData.append('file', d.file.file)
    }
    formData.append('user_define', d.user_define ? 1 : 2)
    this.$post('/api/xapc/file_template', formData, { headers: { 'Content-Type': 'multipart/form-data' } })
      .then(res => {
        hide()
        if (res.status === 1) {
          callback()
          this.getTemplateList()
        } else {
          message.warning(res.message)
        }
      }).catch(() => hide())
  }

  // 修改文档请求
  modifyRequest (d, callback) {
    const hide = message.loading('修改文书模板中', 120)
    const formData = new FormData()
    let url = '/api/xapc/file_template_update/'
    if (d.code_type) {
      formData.append('code_type', d.code_type)
    }
    if (d.title) {
      formData.append('title', d.title)
    }
    if (d.file && d.file.file) {
      formData.append('file', d.file.file)
    }
    if (d.user_define !== undefined) {
      formData.append('user_define', d.user_define ? 1 : 2)
    }
    if (this.state.justyModifyFile) {
      url = '/api/xapc/file_template_update_file/'
    }
    this.$post(`${url}${d.id}`, formData, { headers: { 'Content-Type': 'multipart/form-data' } })
      .then(res => {
        hide()
        if (res.status === 1) {
          callback()
          this.getTemplateList()
        } else {
          message.warning(res.message)
        }
      }).catch(() => hide())
  }

  // 修改文书按钮回调
  modifyHandle (justyModifyFile) {
    const { currentTemplateid, templateIdMap } = this.state
    const template = templateIdMap[currentTemplateid]
    if (!template) {
      return message.warning('文书模板不存在')
    }
    this.setState({
      visible: true,
      modifyTemplate: template,
      justyModifyFile
    })
  }

  // 删除按钮回调
  delHandle () {
    const { currentTemplateid, templateIdMap } = this.state
    const template = templateIdMap[currentTemplateid]
    if (!template) {
      return message.warning('文书模板不存在')
    }
    confirm({
      icon: <ExclamationCircleOutlined />,
      content: `您确定要删除 ${template.title} 吗？`,
      onOk: () => {
        this.delRequest()
      }
    })
  }

  // 删除文书请求
  delRequest () {
    const hide = message.loading('删除文书模板中', 120)
    this.$delete(`/api/xapc/file_template/${this.state.currentTemplateid}`)
      .then(res => {
        hide()
        if (res.status === 1) {
          this.getTemplateList()
          this.setState({
            currentTemplateid: ''
          })
        } else {
          message.warning(res.message)
        }
      }).catch(() => hide())
  }

  // 获取枚举的字典值
  getDictionary () {
    this.$get('/api/xapc/dictionary', {
      types: '文书类别'
    }).then(res => {
      if (res.status === 1) {
        // 设置枚举字典
        const dictionaries = this.formatDictionaries(res.data)
        const list = dictionaries['文书类别']
        this.setState({
          fileTypes: list.map(li => li.title)
        })
      } else {
        message.error(res.message)
      }
    })
  }

  // 格式化枚举字典
  formatDictionaries (dictionaries = []) {
    const result = {}
    dictionaries.forEach(d => {
      result[d.type] = d.list
    })
    return result
  }

  // 改变文书模板类型
  changeDocType (v) {
    this.setState({
      userDefine: v
    }, () => {
      this.getTemplateListAfterFilter()
    })
  }

  componentDidMount () {
    this.getDictionary()
    this.getTemplateList()
    this.props.addScrollEvent({ name: 'fix-document-menu', handle: this.fixHandle.bind(this) })
  }

  componentWillUnmount () {
    this.props.delScrollEvent('fix-document-menu')
  }

  renderItem (d) {
    return <ListItem active={d.id === this.state.currentTemplateid} data={d} selectHandle={id => this.setState({ currentTemplateid: id, file: null }, () => { this.getTemplateById(id) })} />
  }

  // 渲染pdf页面
  renderPages () {
    if (this.state.ready) {
      const arr = []
      for (let i = 0; i < this.state.numPages; i++) {
        arr.push((
          <div className={style.page} key={i}>
            <Page pageNumber={i + 1} width={this.state.width} height={this.state.height} renderTextLayer={false} renderAnnotationLayer={false} />
          </div>
        ))
      }
      return arr
    }
  }

  renderPdf () {
    const { width, height, file } = this.state
    if (!file) {
      return null
    }
    if (!file.pdf_path) {
      return <span>文书生成中</span>
    }
    return (
      <Document
        loading={(
          <div className={style['empty-page']} style={{ width: `${width}px`, height: `${height}px` }}>
            <div>
              <LoadingOutlined className={style['loading-icon']} />
              <div className={style['loading-text']}>加载中</div>
            </div>
          </div>
        )}
        error='文书生成失败。'
        file={`${file.pdf_path}`}
        onLoadSuccess={e => this.initDoc(e)}
        options={{ cMapUrl: 'cmaps/', cMapPacked: true }}
      >
        {this.renderPages()}
      </Document>
    )
  }

  renderBtns () {
    const { currentTemplateid, templateIdMap } = this.state
    const template = currentTemplateid ? templateIdMap[currentTemplateid] : {}
    if (!currentTemplateid) {
      return null
    }
    if (template && template.user_define !== 0) {
      return (
        <>
          <Button type='primary' onClick={() => this.modifyHandle(false)}>修改文书</Button>
          <Button type='primary' ghost onClick={() => this.modifyHandle(true)}>更换模版文件</Button>
          <Button onClick={() => this.delHandle()}>删除文书</Button>
        </>
      )
    }
    return <Button type='primary' ghost onClick={() => this.modifyHandle(true)}>更换模版文件</Button>
  }

  render () {
    const { visible, modifyTemplate } = this.state
    const { fixedMenuStyle } = this.state

    return (
      <div className={style.container}>
        <Model visible={visible} data={modifyTemplate} justyModifyFile={this.state.justyModifyFile} onFinish={(d, callback) => this.submitHandle(d, callback)} hide={() => this.setState({ visible: false, justyModifyFile: false })} fileTypes={this.state.fileTypes} />
        <div className={style['title-line']}>
          <span>{this.props.title}</span>
        </div>
        <div className={style.body}>
          <div className={style['left-block']} style={fixedMenuStyle}>
            <div className={style['menu-box']}>
              <div className={style['menu-search']}>
                <Input value={this.state.searchText} placeholder='请输入文书名称' onChange={e => this.onSearch(e.target.value)} allowClear />
              </div>
              <div className={style['menu-types']}>
                <Select className={style.full} value={this.state.userDefine} placeholder='请选择文书类型' onChange={v => this.changeDocType(v)}>
                  <Option value={0}>系统文书</Option>
                  <Option value={1}>呈批文书</Option>
                  <Option value={2}>非呈批文书</Option>
                </Select>
              </div>
              <div className={style['menu-list']}>
                <FreeScrollBar className='mock'>
                  <List loading={this.state.loadingList} dataSource={this.state.filterTemplateList} renderItem={d => this.renderItem(d)} />
                </FreeScrollBar>
              </div>
              <div className={style['menu-btn']}>
                <Button type='primary' block onClick={() => this.addHandle()}>添加自定义文书</Button>
              </div>
            </div>
          </div>
          <div className={style['right-block']}>
            <div className={style['btn-line']}>
              <Space>
                {this.renderBtns()}
              </Space>
            </div>
            <div className={style['pdf-box']} ref={this.docBoxRef}>
              {this.renderPdf()}
            </div>
          </div>
        </div>
      </div>
    )
  }
}

const mapState = mapStateToProps(function (state) {
  return {
    userInfo: state.basic.userInfo
  }
})

const mapDispatch = mapDispatchToProps(function (dispatch) {
  return {
    delScrollEvent: (i) => dispatch(delScrollEvent(i)),
    addScrollEvent: (i) => dispatch(addScrollEvent(i))
  }
})

export default connect(mapState, mapDispatch)(DocumentManage)

class ListItem extends React.Component {
  render () {
    const { data } = this.props
    const className = [style['menu-option']]
    if (this.props.active) {
      className.push(style.active)
    }
    return (
      <div className={className.join(' ')}><span onClick={() => this.props.selectHandle(data.id)}>{data.title}</span></div>
    )
  }
}
